import * as fs from 'fs';
import { FrontendParser } from '../utils/FrontendParser';

/**
 * Vue组件重构工具
 */
export class VueRefactor {
    
    /**
     * 将Vue 2组件转换为Vue 3 Composition API
     */
    async convertToCompositionAPI(filePath: string): Promise<{
        success: boolean;
        message: string;
        filesModified: string[];
        originalAPI: string;
        compositionAPI: string;
        appliedChanges: string[];
        errors: string[];
    }> {
        const result = {
            success: false,
            message: '',
            filesModified: [] as string[],
            originalAPI: 'Options API',
            compositionAPI: 'Composition API',
            appliedChanges: [] as string[],
            errors: [] as string[]
        };

        try {
            const content = await fs.promises.readFile(filePath, 'utf-8');

            if (!FrontendParser.isVue2Component(content)) {
                result.message = '这不是一个Vue 2 Options API组件，无法转换';
                return result;
            }

            if (FrontendParser.isVue3CompositionComponent(content)) {
                result.message = '该组件已经使用Composition API，无需转换';
                return result;
            }

            // 分析转换机会
            const compositionOpportunities = FrontendParser.analyzeVueCompositionOpportunities(content);

            if (compositionOpportunities.length === 0) {
                result.message = '该组件结构简单，无明显转换价值';
                return result;
            }

            // 执行转换
            const convertedContent = await this.performCompositionAPIConversion(content, compositionOpportunities);
            
            // 备份原文件
            const backupPath = filePath.replace('.vue', '.options-backup.vue');
            await fs.promises.writeFile(backupPath, content);

            // 写入转换后的内容
            await fs.promises.writeFile(filePath, convertedContent);

            result.success = true;
            result.message = `成功转换为Composition API，应用了${compositionOpportunities.length}个优化`;
            result.filesModified = [filePath];
            result.appliedChanges = compositionOpportunities.map(op => `${op.type}: ${op.suggestion}`);

        } catch (error) {
            result.errors.push(`转换失败: ${error}`);
            result.message = `转换失败: ${error}`;
        }

        return result;
    }

    /**
     * 优化Vue组件性能
     */
    async optimizeVuePerformance(filePath: string): Promise<{
        success: boolean;
        message: string;
        filesModified: string[];
        optimizations: Array<{
            type: string;
            description: string;
            applied: boolean;
        }>;
        appliedChanges: string[];
        errors: string[];
    }> {
        const result = {
            success: false,
            message: '',
            filesModified: [] as string[],
            optimizations: [] as Array<{
                type: string;
                description: string;
                applied: boolean;
            }>,
            appliedChanges: [] as string[],
            errors: [] as string[]
        };

        try {
            const content = await fs.promises.readFile(filePath, 'utf-8');
            let optimizedContent = content;
            const optimizations: Array<{
                type: string;
                description: string;
                applied: boolean;
            }> = [];

            // 1. 添加v-memo指令建议
            if (!content.includes('v-memo') && content.includes('v-for')) {
                optimizations.push({
                    type: 'v-memo',
                    description: '建议在大列表中使用v-memo指令优化渲染',
                    applied: false
                });
            }

            // 2. 优化computed属性
            const computedOptimization = this.optimizeComputedProperties(optimizedContent);
            if (computedOptimization.modified) {
                optimizedContent = computedOptimization.content;
                optimizations.push({
                    type: 'computed-optimization',
                    description: '优化computed属性的依赖追踪',
                    applied: true
                });
                result.appliedChanges.push('优化computed属性');
            }

            // 3. 添加key属性优化
            const keyOptimization = this.optimizeListKeys(optimizedContent);
            if (keyOptimization.modified) {
                optimizedContent = keyOptimization.content;
                optimizations.push({
                    type: 'key-optimization',
                    description: '优化列表渲染的key属性',
                    applied: true
                });
                result.appliedChanges.push('优化列表key');
            }

            // 4. 函数式组件建议
            if (this.canBeFunctionalComponent(content)) {
                optimizations.push({
                    type: 'functional-component',
                    description: '该组件可以转换为函数式组件以提升性能',
                    applied: false
                });
            }

            if (optimizedContent !== content) {
                await fs.promises.writeFile(filePath, optimizedContent);
                result.filesModified = [filePath];
            }

            result.success = true;
            result.message = `应用了${result.appliedChanges.length}个性能优化`;
            result.optimizations = optimizations;

        } catch (error) {
            result.errors.push(`性能优化失败: ${error}`);
            result.message = `优化失败: ${error}`;
        }

        return result;
    }

    /**
     * 提取Vue组合式函数
     */
    async extractComposables(filePath: string): Promise<{
        success: boolean;
        message: string;
        filesModified: string[];
        extractedComposables: Array<{
            name: string;
            filePath: string;
            description: string;
        }>;
        appliedChanges: string[];
        errors: string[];
    }> {
        const result = {
            success: false,
            message: '',
            filesModified: [] as string[],
            extractedComposables: [] as Array<{
                name: string;
                filePath: string;
                description: string;
            }>,
            appliedChanges: [] as string[],
            errors: [] as string[]
        };

        try {
            const content = await fs.promises.readFile(filePath, 'utf-8');
            const composableSuggestions = this.analyzeComposableOpportunities(content);

            if (composableSuggestions.length === 0) {
                result.message = '未发现可以提取的组合式函数模式';
                return result;
            }

            const extractedComposables: Array<{
                name: string;
                filePath: string;
                description: string;
            }> = [];

            for (const suggestion of composableSuggestions) {
                const composableContent = this.generateComposable(suggestion);
                const composableFilePath = this.generateComposableFilePath(filePath, suggestion.name);
                
                await fs.promises.writeFile(composableFilePath, composableContent);
                
                extractedComposables.push({
                    name: suggestion.name,
                    filePath: composableFilePath,
                    description: suggestion.description
                });

                result.appliedChanges.push(`提取组合式函数: ${suggestion.name}`);
            }

            // 更新原组件，使用新的组合式函数
            const updatedContent = this.updateComponentToUseComposables(content, composableSuggestions);
            await fs.promises.writeFile(filePath, updatedContent);

            result.success = true;
            result.message = `成功提取了${extractedComposables.length}个组合式函数`;
            result.filesModified = [filePath, ...extractedComposables.map(c => c.filePath)];
            result.extractedComposables = extractedComposables;

        } catch (error) {
            result.errors.push(`提取组合式函数失败: ${error}`);
            result.message = `提取失败: ${error}`;
        }

        return result;
    }

    /**
     * 执行Options API到Composition API的转换
     */
    private async performCompositionAPIConversion(
        content: string,
        opportunities: Array<{type: string; suggestion: string; original: string; replacement: string}>
    ): Promise<string> {
        let converted = content;
        
        // 1. 提取和转换各个部分
        const dataProperties = this.extractDataProperties(converted);
        const computedProperties = this.extractComputedProperties(converted);
        const methods = this.extractMethods(converted);
        const lifecycle = this.extractLifecycleMethods(converted);
        const watchers = this.extractWatchers(converted);
        
        // 2. 构建setup函数
        const setupFunction = this.buildSetupFunction(dataProperties, computedProperties, methods, lifecycle, watchers);
        
        // 3. 替换原来的Options API结构
        converted = this.replaceWithCompositionAPI(converted, setupFunction);
        
        // 4. 更新script标签的import
        converted = this.updateImports(converted);
        
        return converted;
    }

    private extractDataProperties(content: string): Array<{name: string; value: string}> {
        const dataMatch = content.match(/data\s*\(\s*\)\s*\{[\s\S]*?return\s*\{([\s\S]*?)\}/);
        const properties: Array<{name: string; value: string}> = [];
        
        if (dataMatch) {
            const dataContent = dataMatch[1];
            const lines = dataContent.split('\n');
            
            for (const line of lines) {
                const propMatch = line.trim().match(/(\w+):\s*(.+),?/);
                if (propMatch) {
                    properties.push({
                        name: propMatch[1],
                        value: propMatch[2].replace(/,$/, '')
                    });
                }
            }
        }
        
        return properties;
    }

    private extractComputedProperties(content: string): Array<{name: string; getter: string; setter?: string}> {
        const computedMatch = content.match(/computed\s*:\s*\{([\s\S]*?)\}/);
        const properties: Array<{name: string; getter: string; setter?: string}> = [];
        
        if (computedMatch) {
            const computedContent = computedMatch[1];
            // 简化实现：提取基本的computed属性
            const propMatches = computedContent.match(/(\w+)\s*\(\s*\)\s*\{([\s\S]*?)\}/g);
            
            if (propMatches) {
                for (const match of propMatches) {
                    const propMatch = match.match(/(\w+)\s*\(\s*\)\s*\{([\s\S]*?)\}/);
                    if (propMatch) {
                        properties.push({
                            name: propMatch[1],
                            getter: propMatch[2].trim()
                        });
                    }
                }
            }
        }
        
        return properties;
    }

    private extractMethods(content: string): Array<{name: string; body: string}> {
        const methodsMatch = content.match(/methods\s*:\s*\{([\s\S]*?)\}/);
        const methods: Array<{name: string; body: string}> = [];
        
        if (methodsMatch) {
            const methodsContent = methodsMatch[1];
            const methodMatches = methodsContent.match(/(\w+)\s*\([^)]*\)\s*\{([\s\S]*?)\}/g);
            
            if (methodMatches) {
                for (const match of methodMatches) {
                    const methodMatch = match.match(/(\w+)\s*\([^)]*\)\s*\{([\s\S]*?)\}/);
                    if (methodMatch) {
                        methods.push({
                            name: methodMatch[1],
                            body: methodMatch[2].trim()
                        });
                    }
                }
            }
        }
        
        return methods;
    }

    private extractLifecycleMethods(content: string): Array<{name: string; body: string}> {
        const lifecycleMethods: Array<{name: string; body: string}> = [];
        const lifecycleNames = ['created', 'mounted', 'updated', 'beforeDestroy', 'destroyed'];
        
        for (const name of lifecycleNames) {
            const regex = new RegExp(`${name}\\s*\\(\\s*\\)\\s*\\{([\\s\\S]*?)\\}`, 'g');
            const match = regex.exec(content);
            
            if (match) {
                lifecycleMethods.push({
                    name,
                    body: match[1].trim()
                });
            }
        }
        
        return lifecycleMethods;
    }

    private extractWatchers(content: string): Array<{property: string; handler: string}> {
        const watchMatch = content.match(/watch\s*:\s*\{([\s\S]*?)\}/);
        const watchers: Array<{property: string; handler: string}> = [];
        
        if (watchMatch) {
            const watchContent = watchMatch[1];
            const watcherMatches = watchContent.match(/(\w+)\s*\([^)]*\)\s*\{([\s\S]*?)\}/g);
            
            if (watcherMatches) {
                for (const match of watcherMatches) {
                    const watcherMatch = match.match(/(\w+)\s*\([^)]*\)\s*\{([\s\S]*?)\}/);
                    if (watcherMatch) {
                        watchers.push({
                            property: watcherMatch[1],
                            handler: watcherMatch[2].trim()
                        });
                    }
                }
            }
        }
        
        return watchers;
    }

    private buildSetupFunction(
        dataProperties: Array<{name: string; value: string}>,
        computedProperties: Array<{name: string; getter: string; setter?: string}>,
        methods: Array<{name: string; body: string}>,
        lifecycle: Array<{name: string; body: string}>,
        watchers: Array<{property: string; handler: string}>
    ): string {
        let setup = '    setup() {\n';
        
        // 转换data为ref/reactive
        for (const prop of dataProperties) {
            if (this.isPrimitiveValue(prop.value)) {
                setup += `      const ${prop.name} = ref(${prop.value});\n`;
            } else {
                setup += `      const ${prop.name} = reactive(${prop.value});\n`;
            }
        }
        
        if (dataProperties.length > 0) setup += '\n';
        
        // 转换computed
        for (const comp of computedProperties) {
            setup += `      const ${comp.name} = computed(() => {\n`;
            setup += `        ${comp.getter}\n`;
            setup += `      });\n`;
        }
        
        if (computedProperties.length > 0) setup += '\n';
        
        // 转换methods
        for (const method of methods) {
            setup += `      const ${method.name} = () => {\n`;
            setup += `        ${method.body}\n`;
            setup += `      };\n`;
        }
        
        if (methods.length > 0) setup += '\n';
        
        // 转换lifecycle
        for (const hook of lifecycle) {
            const compositionHook = this.mapLifecycleToComposition(hook.name);
            if (compositionHook) {
                setup += `      ${compositionHook}(() => {\n`;
                setup += `        ${hook.body}\n`;
                setup += `      });\n`;
            }
        }
        
        if (lifecycle.length > 0) setup += '\n';
        
        // 转换watchers
        for (const watcher of watchers) {
            setup += `      watch(${watcher.property}, (newVal, oldVal) => {\n`;
            setup += `        ${watcher.handler}\n`;
            setup += `      });\n`;
        }
        
        if (watchers.length > 0) setup += '\n';
        
        // return语句
        setup += '      return {\n';
        
        // 返回所有响应式数据
        for (const prop of dataProperties) {
            setup += `        ${prop.name},\n`;
        }
        
        // 返回computed
        for (const comp of computedProperties) {
            setup += `        ${comp.name},\n`;
        }
        
        // 返回methods
        for (const method of methods) {
            setup += `        ${method.name},\n`;
        }
        
        setup += '      };\n';
        setup += '    }';
        
        return setup;
    }

    private isPrimitiveValue(value: string): boolean {
        const trimmed = value.trim();
        return /^(true|false|\d+|'.*'|".*"|null|undefined)$/.test(trimmed) ||
               (!trimmed.startsWith('{') && !trimmed.startsWith('['));
    }

    private mapLifecycleToComposition(lifecycleName: string): string | null {
        const mapping: Record<string, string> = {
            'created': 'onBeforeMount',
            'mounted': 'onMounted',
            'updated': 'onUpdated',
            'beforeDestroy': 'onBeforeUnmount',
            'destroyed': 'onUnmounted'
        };
        
        return mapping[lifecycleName] || null;
    }

    private replaceWithCompositionAPI(content: string, setupFunction: string): string {
        // 移除原来的Options API部分，保留template和style
        let result = content;
        
        // 替换script部分
        const scriptMatch = content.match(/(<script[^>]*>)([\s\S]*?)(<\/script>)/);
        if (scriptMatch) {
            const newScript = `${scriptMatch[1]}
export default {
  name: '${this.extractComponentName(content)}',
${setupFunction}
}
${scriptMatch[3]}`;
            
            result = result.replace(scriptMatch[0], newScript);
        }
        
        return result;
    }

    private updateImports(content: string): string {
        // 添加Composition API的import
        const importMatch = content.match(/import.*from\s+['"]vue['"];?/);
        if (importMatch) {
            const newImport = `import { ref, reactive, computed, watch, onMounted, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';`;
            return content.replace(importMatch[0], newImport);
        } else {
            // 如果没有vue的import，添加一个
            const scriptMatch = content.match(/(<script[^>]*>)/);
            if (scriptMatch) {
                return content.replace(
                    scriptMatch[0],
                    `${scriptMatch[0]}\nimport { ref, reactive, computed, watch, onMounted, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';\n`
                );
            }
        }
        
        return content;
    }

    private extractComponentName(content: string): string {
        const nameMatch = content.match(/name\s*:\s*['"]([^'"]+)['"]/);
        if (nameMatch) {
            return nameMatch[1];
        }
        
        return 'Component';
    }

    private optimizeComputedProperties(content: string): {modified: boolean; content: string} {
        // 简化实现：检查computed属性是否可以优化
        let modified = false;
        let optimized = content;
        
        // 检查是否有不必要的computed属性可以改为methods
        const simpleComputedPattern = /(\w+)\s*\(\s*\)\s*\{\s*return\s+([^}]+)\s*\}/g;
        const matches = content.match(simpleComputedPattern);
        
        if (matches) {
            // 这里可以添加具体的优化逻辑
            modified = true;
        }
        
        return {modified, content: optimized};
    }

    private optimizeListKeys(content: string): {modified: boolean; content: string} {
        let modified = false;
        let optimized = content;
        
        // 检查v-for是否缺少key或使用了index作为key
        const vForPattern = /v-for="[^"]*"\s*(?!.*:key)/g;
        const matches = content.match(vForPattern);
        
        if (matches) {
            // 建议添加唯一key
            optimized = content.replace(
                vForPattern,
                '$& :key="item.id" // TODO: 使用唯一标识符'
            );
            modified = true;
        }
        
        return {modified, content: optimized};
    }

    private canBeFunctionalComponent(content: string): boolean {
        // 检查组件是否只有template和props，没有状态
        return !content.includes('data(') && 
               !content.includes('methods:') && 
               !content.includes('computed:') && 
               !content.includes('watch:');
    }

    private analyzeComposableOpportunities(content: string): Array<{
        name: string;
        description: string;
        logic: string[];
        type: 'api' | 'form' | 'state' | 'utility';
    }> {
        const opportunities: Array<{
            name: string;
            description: string;
            logic: string[];
            type: 'api' | 'form' | 'state' | 'utility';
        }> = [];
        
        // 检测API调用模式
        if (content.includes('axios') || content.includes('fetch(')) {
            opportunities.push({
                name: 'useApi',
                description: 'API调用和状态管理',
                logic: ['loading状态', 'error处理', 'data管理'],
                type: 'api'
            });
        }
        
        // 检测表单处理
        if (content.includes('v-model') && content.includes('validate')) {
            opportunities.push({
                name: 'useForm',
                description: '表单状态和验证',
                logic: ['表单数据', '验证规则', '提交处理'],
                type: 'form'
            });
        }
        
        return opportunities;
    }

    private generateComposable(suggestion: {name: string; description: string; logic: string[]; type: string}): string {
        return `import { ref, reactive, computed } from 'vue';

/**
 * ${suggestion.description}
 */
export function ${suggestion.name}() {
  // TODO: 实现${suggestion.description}的逻辑
  ${suggestion.logic.map(logic => `  // ${logic}`).join('\n')}
  
  return {
    // 返回需要的响应式数据和方法
  };
}
`;
    }

    private generateComposableFilePath(originalPath: string, composableName: string): string {
        const dir = originalPath.substring(0, originalPath.lastIndexOf('/'));
        const fileName = composableName.replace(/([A-Z])/g, '-$1').toLowerCase();
        return `${dir}/composables/${fileName}.js`;
    }

    private updateComponentToUseComposables(
        content: string, 
        suggestions: Array<{name: string}>
    ): string {
        let updated = content;
        
        // 在setup函数中添加组合式函数的使用
        const setupMatch = content.match(/(setup\s*\(\s*\)\s*\{)/);
        if (setupMatch) {
            const composableUsage = suggestions.map(s => `      const ${s.name.replace('use', '').toLowerCase()} = ${s.name}();`).join('\n');
            updated = updated.replace(
                setupMatch[0],
                `${setupMatch[0]}\n${composableUsage}\n`
            );
        }
        
        return updated;
    }
}